<?php

namespace common\models;

use common\helpers\predis\Predis;
use common\service\ConcernService;
use common\service\ServiceFactory;
use yii\behaviors\TimestampBehavior;
use yii\mongodb\Database;
use yii\web\IdentityInterface;
use yii;

/**
 * This is the model class for table "mops_user".
 *
 * @property int $id
 * @property string $customer_id CustomerId
 * @property string $avatar 头像
 * @property string $phone 手机号
 * @property int $created_at 创建时间
 * @property int $updated_at 更新时间
 * @property string $nickname 昵称
 * @property string $open_id openId
 * @property int $status
 */
class User extends \yii\db\ActiveRecord implements IdentityInterface
{
    protected $_password;

    public $token;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%user}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['phone'], 'required'],
            [['created_at', 'updated_at','status'], 'integer'],
            [['open_id', 'customer_id', 'phone'], 'unique'],
            [['avatar', 'open_id', 'customer_id', 'nickname'], 'string', 'max' => 255],
            [['phone'], 'string', 'max' => 11],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'customer_id' => 'CustomerId',
            'avatar' => "头像",
            'phone' => "手机号",
            'created_at' => '创建时间',
            'updated_at' => '更新时间',
            'nickname' => "昵称",
            'open_id' => 'OpenId',
            'status' =>'是否领过券',
        ];
    }

    public function behaviors()
    {
        return [
            TimestampBehavior::className()
        ];
    }


    /**
     * Finds an identity by the given ID.
     * @param string|int $id the ID to be looked for
     * @return IdentityInterface the identity object that matches the given ID.
     * Null should be returned if such an identity cannot be found
     * or the identity is not in an active state (disabled, deleted, etc.)
     */
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    /**
     * Finds an identity by the given token.
     * @param mixed $token the token to be looked for
     * @param mixed $type the type of the token. The value of this parameter depends on the implementation.
     * For example, [[\yii\filters\auth\HttpBearerAuth]] will set this parameter to be `yii\filters\auth\HttpBearerAuth`.
     * @return IdentityInterface the identity object that matches the given token.
     * Null should be returned if such an identity cannot be found
     * or the identity is not in an active state (disabled, deleted, etc.)
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        $user = Predis::getInstance()->getClient()->client->hgetall($token);

        if (!empty($user)) {
            $tokenUser = new User();
            $tokenUser->phone = $user['phone'];
            $tokenUser->id = $user['id'];
            $tokenUser->customer_id = $user['customer_id'];
            $tokenUser->open_id = $user['open_id'];
            $tokenUser->nickname = $user['nickname'];
            $tokenUser->avatar = $user['avatar'];
            $tokenUser->status = $user['status'];
            return $tokenUser;
        }
        return null;
    }

    /**
     * Returns an ID that can uniquely identify a user identity.
     * @return string|int an ID that uniquely identifies a user identity.
     */
    public function getId()
    {
        return $this->getPrimaryKey();
    }

    /**
     * Returns a key that can be used to check the validity of a given identity ID.
     *
     * The key should be unique for each individual user, and should be persistent
     * so that it can be used to check the validity of the user identity.
     *
     * The space of such keys should be big enough to defeat potential identity attacks.
     *
     * This is required if [[User::enableAutoLogin]] is enabled.
     * @return string a key that is used to check the validity of a given identity ID.
     * @see validateAuthKey()
     */
    public function getAuthKey()
    {
        return null;
    }

    /**
     * Validates the given auth key.
     *
     * This is required if [[User::enableAutoLogin]] is enabled.
     * @param string $authKey the given auth key
     * @return bool whether the given auth key is valid.
     * @see getAuthKey()
     */
    public function validateAuthKey($authKey)
    {
        return null;
    }


    /**
     * @param $phone string
     * @param $user
     */
    public static function refreshToken($phone, $user)
    {
        $userArr = ['id' => $user->id, 'phone' => $user->phone, 'open_id' => $user->open_id, 'customer_id' => $user->customer_id, 'nickname' => $user->nickname, 'avatar' => $user->avatar,'status'=>$user->status];
        $preString = "user_token_" . $phone;
        $pRedis = Predis::getInstance()->getClient();
        $oldToken = $pRedis->client->get($preString);
        if (!empty($oldToken)) {
            $pRedis->client->del([$oldToken, $preString]);
        }
        $newToken = Yii::$app->security->generateRandomString(32);
        $pRedis->client->set($preString, $newToken);
        $pRedis->client->hMset($newToken, $userArr);
        $timeOut = 5 * 3600;
        $pRedis->client->expire($preString, $timeOut);
        $pRedis->client->expire($newToken, $timeOut);
        return $newToken;
    }


    public function getErrorMsg()
    {
        $errMsgArr = $this->getErrors();
        $errStr = '';
        if (count($errMsgArr)) {
            foreach ($errMsgArr as $errMsg) {
                $errStr .= $errMsg[0];
            }
        }
        return $errStr;
    }


    public static function getCollection()
    {
        /** @var Database $database */
        $database = Yii::$app->mongo->getDatabase();
        return $collection = $database->getCollection("user");
    }


    public function objToArr()
    {
        return [
            'id' => $this->id,
            'customer_id' => $this->customer_id,
            'open_id' => $this->open_id,
            'nickname' => $this->nickname,
            'avatar' => $this->avatar,
            'status' => intval($this->status),
            'phone' => $this->phone,
            'created_at' => intval($this->created_at),
            'updated_at' => intval($this->updated_at),
        ];
    }

    public function afterDelete()
    {
        $collection = self::getCollection();
        $collection->remove(['id' => $this->id]);

        UserCoupon::deleteAll(['user_id' => $this->id]);
        UserCoupon::getCollection()->remove(['user_id' => $this->id]);

        return true;
    }

    public function fields()
    {
        $field = parent::fields(); // TODO: Change the autogenerated stub
        $field['token'] = function () {
            return $this->token;
        };
        return $field;
    }

    public function afterSave($insert, $changedAttributes)
    {
        $collection = self::getCollection();
        $find = $collection->findOne(['id' => $this->id]);
        if ($find) {
            $collection->update(['id' => $this->id], $this->objToArr());
        } else {
            $collection->insert($this->objToArr());
        }
        return true;
    }
}
